﻿#include "stdafx.h"

using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace	Microsoft::VisualStudio::TestTools::UnitTesting;
using namespace std;

namespace TestProject1
{
	[TestClass]
	public ref class EncoderTest
	{
	public: 

		[TestMethod]
		void DecodingTest()
		{	
			char word[] = "arytmetyka";
			for (int i = 0; i < 15; ++i)
			{
				word[9] += 1;
				MockProbabilityModel model(word, strlen(word));
				ArithmeticEncoder encoder(&model);
				ArithmeticDecoder decoder(&model);
				unsigned long long symbolsEncoded = 0;
				BitBuffer bufferWithCode = encoder.encodeString(word, &symbolsEncoded, strlen(word));

				bufferWithCode.resetPointers();
				char* result = new char[bufferWithCode.getSize()];
				result = decoder.decodeBitStream(bufferWithCode, symbolsEncoded);
				Assert::AreEqual<String^>(gcnew String(word), gcnew String(result), "Wrong value decoded");
			}
		}

		[TestMethod]
		void DecodingTest2()
		{
			MockProbabilityModel model("ekstraklasa", strlen("ekstraklasa"));
			ArithmeticEncoder encoder(&model);
			ArithmeticDecoder decoder(&model);
			unsigned long long symbolsEncoded = 0;
			BitBuffer bufferWithCode = encoder.encodeString("ekstraklasa", &symbolsEncoded, strlen("ekstraklasa"));

			bufferWithCode.resetPointers();
			char* result = new char[bufferWithCode.getSize()];
			result = decoder.decodeBitStream(bufferWithCode, symbolsEncoded);
			Assert::AreEqual<String^>("ekstraklasa", gcnew String(result), "Wrong value decoded");
		}

		[TestMethod]
		void DecodingTest3()
		{	
			MockProbabilityModel model("arytmetyka", strlen("arytmetyka"), 2);
			ArithmeticEncoder encoder(&model);
			ArithmeticDecoder decoder(&model);
			unsigned long long symbolsEncoded = 0;
			BitBuffer bufferWithCode = encoder.encodeString("arytmetyka", &symbolsEncoded, strlen("arytmetyka"));

			bufferWithCode.resetPointers();
			char* result = new char[bufferWithCode.getSize()];
			result = decoder.decodeBitStream(bufferWithCode, symbolsEncoded);
			Assert::AreEqual<String^>("arytmetyka", gcnew String(result), "Wrong value decoded");
		}

		[TestMethod]
		void DecodingTest4()
		{
			MockProbabilityModel model("ekstraklasa", strlen("ekstraklasa"), 2);
			ArithmeticEncoder encoder(&model);
			ArithmeticDecoder decoder(&model);
			unsigned long long symbolsEncoded = 0;
			BitBuffer bufferWithCode = encoder.encodeString("ekstraklasa", &symbolsEncoded, strlen("ekstraklasa"));

			bufferWithCode.resetPointers();
			char* result = new char[bufferWithCode.getSize()];
			result = decoder.decodeBitStream(bufferWithCode, symbolsEncoded);
			Assert::AreEqual<String^>("ekstraklasa", gcnew String(result), "Wrong value decoded");
		}

		[TestMethod]
		void DecodingTest5()
		{	
			char word[] = "arytmetyka";
			for (int i = 0; i < 20; ++i)
			{
				MockProbabilityModel model(word, strlen(word), 1);
				ArithmeticEncoder encoder(&model);
				ArithmeticDecoder decoder(&model);
				unsigned long long symbolsEncoded = 0;
				BitBuffer bufferWithCode = encoder.encodeString(word, &symbolsEncoded, strlen(word));

				bufferWithCode.resetPointers();
				char* result = new char[bufferWithCode.getSize()];
				result = decoder.decodeBitStream(bufferWithCode, symbolsEncoded);
				Assert::AreEqual<String^>(gcnew String(word), gcnew String(result), "Wrong value decoded");
				word[0] += 1;
			}
		}

		[TestMethod]
		void DecodingTest6()
		{
			char word[] = "ekstraklasa";
			for (int i = 0; i < 20; ++i)
			{
				MockProbabilityModel model(word, strlen(word), 1);
				ArithmeticEncoder encoder(&model);
				ArithmeticDecoder decoder(&model);
				unsigned long long symbolsEncoded = 0;
				BitBuffer bufferWithCode = encoder.encodeString(word, &symbolsEncoded, strlen(word));

				bufferWithCode.resetPointers();
				char* result = new char[bufferWithCode.getSize()];
				result = decoder.decodeBitStream(bufferWithCode, symbolsEncoded);
				Assert::AreEqual<String^>(gcnew String(word), gcnew String(result), "Wrong value decoded");
				word[0] += 1;
			}
		}

		[TestMethod]
		void ContextTreeTest1()
		{
			char word[] = " kstraklasa";
			for (int i = 0; i < 200; ++i)
			{
				ContextTree tree(1, 1);
				ContextTree decodeTree(1, 1);
				ArithmeticEncoder encoder(&tree, 1, 1);
				ArithmeticDecoder decoder(&decodeTree, 1, 1);
				unsigned long long symbolsEncoded = 0;
				BitBuffer bufferWithCode = encoder.encodeString(word, &symbolsEncoded, strlen(word));

				bufferWithCode.resetPointers();
				char* result = new char[bufferWithCode.getSize()];
				result = decoder.decodeBitStream(bufferWithCode, symbolsEncoded);
				Assert::AreEqual<String^>(gcnew String(word), gcnew String(result), "Wrong value decoded");
				word[0] += 1;
			}
		}

		[TestMethod]
		void ContextTreeTest2()
		{
			char word[] = " rytmetyka";
			int model = 2;
			int block = 2;
			for (int i = 0; i < 200; ++i)
			{
				ContextTree tree(block, model);
				ContextTree decodeTree(block, model);
				ArithmeticEncoder encoder(&tree, model, block);
				ArithmeticDecoder decoder(&decodeTree, model, block);
				unsigned long long symbolsEncoded = 0;
				BitBuffer bufferWithCode = encoder.encodeString(word, &symbolsEncoded, strlen(word));

				bufferWithCode.resetPointers();
				char* result = new char[bufferWithCode.getSize()];
				result = decoder.decodeBitStream(bufferWithCode, symbolsEncoded);
				Assert::AreEqual<String^>(gcnew String(word), gcnew String(result), "Wrong value decoded");
				word[0] += 1;
			}
		}
	};
}
